#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

#define MAXN 12

int N, W, H;
int MAP[MAXN][MAXN];
int IND[MAXN][MAXN];
int ans;

struct Node {
    int MAP1[MAXN][MAXN];
    int W, H;

    bool judge(const Node & rhs) const {
        bool ok = true;
        if (W != rhs.W || H != rhs.H) return false;
        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                if (MAP1[i][j] != rhs.MAP1[i][j]) {
                    ok = false;
                    break;
                }
            }
            if (!ok) break;
        }
        if (ok) return true;
        ok = true;
        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                if (MAP1[i][j] != rhs.MAP1[i][W-j-1]) {
                    ok = false;
                    break;
                }
            }
            if (!ok) break;
        }
        if (ok) return true;
        ok = true;
        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                if (MAP1[i][j] != rhs.MAP1[H-i-1][j]) {
                    ok = false;
                    break;
                }
            }
            if (!ok) break;
        }
        if (ok) return true;
        ok = true;
        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                if (MAP1[i][j] != rhs.MAP1[H-i-1][W-j-1]) {
                    ok = false;
                    break;
                }
            }
            if (!ok) break;
        }
        if (ok) return true;
        return false;
    }

    bool operator == (const Node & rhs) const {
        if (W == rhs.H && H == rhs.W) {
            Node t = {{0}, rhs.H, rhs.W};
            for (int i=0; i<H; i++) {
                for (int j=0; j<W; j++) {
                    t.MAP1[i][j] = rhs.MAP1[j][i];
                }
            }
            if (judge(t)) return true;
        }
        return judge(rhs);
    }
};

vector<Node> history;
int cnt;

int dir[4][2] = {{0,1}, {1,0}, {0,-1}, {-1,0}};

void print(int (*p)[MAXN], int h, int w) {
    for (int i=0; i<H; i++) {
        for (int j=0; j<W; j++) {
            printf("%d", p[i][j]);
        }
        printf("\n");
    }
    printf("H:%d | W:%d\n\n", h, w);
}

void DFS(int x, int y, int h, int w, int n, int xi, int yi) {
    if (n >= N) {
        MAP[x][y] = 1;
        Node aa = {{0}, w, h};
        for (int i=0; i<H; i++) {
            for (int j=0; j<W; j++) {
                aa.MAP1[i][j] = MAP[i][j];
            }
        }
        print(MAP, h, w);
        cnt++;
        if (find(history.begin(), history.end(), aa) == history.end()) {
            history.push_back(aa);
            ans++;
            printf("True\n\n");
        } else {
            vector<Node>::iterator it = find(history.begin(), history.end(), aa);
            printf("!!! Duplicate:\n");
            print((*it).MAP1, (*it).H, (*it).W);
        }
        MAP[x][y] = 0;
        return;
    }
    MAP[x][y] = 1;
    int ni = yi;
    for (int i=0; i<4; i++) {
        int nx = x+dir[i][0];
        int ny = y+dir[i][1];
        if (nx < H && ny < W) {
            if (!IND[nx][ny]) {
                IND[nx][ny] = ++ni;
            }
        }
    }
    for (int i=0; i<H; i++) {
        for (int j=0; j<W; j++) {
            if (!MAP[i][j] && IND[i][j] && IND[i][j] > xi) {
                int nh = max(i+1, h);
                int nw = max(j+1, w);
                DFS(i, j, nh, nw, n+1, IND[i][j], ni);
            }
        }
    }
    for (int i=0; i<4; i++) {
        int nx = x+dir[i][0];
        int ny = y+dir[i][1];
        if (nx < H && ny < W) {
            if (IND[nx][ny] > yi) {
                IND[nx][ny] = 0;
            }
        }
    }
    MAP[x][y] = 0;
}


int main()
{
    scanf("%d%d%d", &N, &W, &H);
    IND[0][0] = -1;
    DFS(0, 0, 1, 1, 1, 0, 0);
    printf("%d\n%d\n", cnt, ans);
    return 0;
}
